<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Mineral as MineralModel;
use app\common\model\User;
use app\common\model\Tokenlog;
use app\common\model\MineralLog;
use app\common\model\Takeico;
use think\Hook;

/**
 * 矿机接口
 */
class Mineral extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部00
    protected $noNeedLogin = [];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = '*';

    /**
     * 初始化 
     * @return [type]
     */
    public function _initialize()
    {
        parent::_initialize();
        $auth = $this->auth;
        Hook::add('check_paypwd', function ($paypwd) use ($auth) {
            if ($auth->getUser()['payplaintext'] != $paypwd) {
                $this->error('安全密码不正确');
            }
        });
        
        //注册钩子 用于计算矿机
        // Hook::listen("user_login_successed", $this->auth->getUser(),500);
        Hook::add('user_buy_mineral', function ($user,$buy_mineral) {
            $price = config('site.mineral_price');
            $buynum = $buy_mineral/$price;
            if ($user->active == 0 &&  $user->level==0) {
                $user->level = 1;
            }
            $user->active = 1;
            $user->save();
            
            $usermodel = new User();
            if ($user->path) {
                // $num = $this->getmineralnum($this->auth->id); //用户矿机运行数量
                $rule = config('site.mineral_rule');
                // $depth = $user->depth - count($rule);
                
                //查找血缘关系  会员状态正常  并且属于激活状态
                $referee_frame = $usermodel
                    ->where('id','in','0'.$user->path.'0')
                    // ->where('level','>=',$user->level)
                    ->where('status','normal')
                    // ->where('active',1)
                    ->order('id desc')
                    ->select();
                $user_level = $user->level;//会员需要高过这个等级
                $now_level = $user->level;//会员需要高过这个等级
                $now_index = 1;
                foreach ($referee_frame as $key => $referee) {
                    $re_num = $this->getmineralnum($referee->id);//上级的矿机运行数量
                    $min_num = min($buynum,$re_num);//烧伤制度，取两家矿机最小值
                    $buy_mineral=$min_num*$price;
                    // echo "{re_num}:=".$re_num."{buy_mineral}=".$buy_mineral;
                    // echo "referee=".$referee->level."===now_level=".$now_level;
                    if ($referee->level > $now_level && $referee->level > $user_level) {
                        
                        // var_dump($gain);
                        $gain = bcmul($buy_mineral, bcdiv($rule[$now_index], 100,3),4);
                        $now_level = $referee->level;
                        // ++$now_level;
                        User::tokenlog('DUSD',$referee->id,$user->id,$gain,'synergetic','协同挖矿');
                    }elseif($now_index == 1){
                        // $now_level >= $referee->level && 
                        $gain = bcmul($buy_mineral, bcdiv($rule[$now_index], 100,3),4);
                        // ++$now_level;
                        $now_level = $referee->level;
                        User::tokenlog('DUSD',$referee->id,$user->id,$gain,'synergetic','协同挖矿');
                    }
                    ++$now_index;
                }
            }

            $referee_id = $user->referee_id;

            while ($referee_id) {
                $re_user = $usermodel->where('id',$referee_id)->find();
                if (!$re_user || $re_user->level == 10) {
                    break;
                }

                $re_num =$usermodel->where('level','>=',$re_user->level)->where('referee_id',$referee_id)->count();

                if ($re_num == 3) {
                    $usermodel->inc('level',1)->update(['id'=>$referee_id]);
                    $referee_id = $re_user->referee_id;
                }else{
                    break;
                }
            }
            // if ($user->referee_id) {
            //     $re_user = $usermodel->where('id',$user->referee_id)->find();
            //     $re_num = $usermodel->where('level','>=',$user->level)->where('referee_id',$user->referee_id)->count();
            //     if ($re_user->level == $user->level) {
            //         if ($re_num >= 3) {
            //             $usermodel->inc('level',1)->update(['id'=>$user->referee_id]);
            //         }
            //     }
            // }
        });
    }

    /**
     * 获取购买矿机的信息
     * 矿机价格、最高产能、最长运行时间
     */
    public function init()
    {
        $price = config('site.mineral_price');
        $yield = config('site.mineral_yield');
        $expiretime = config('site.mineral_expiretime');
        //矿机上限
        $mineral_total = config('site.mineral_total');

        $transport_min = config('site.mineral_transport_min');
        $transport_multiple = config('site.mineral_transport_multiple');

        $mineral_takefto_min = config('site.mineral_takefto_min');
        $mineral_takefto_poundage = config('site.mineral_takefto_poundage');

        $mineral_ad = config('site.mineral_ad');

        $tokenlog = new Tokenlog();
        $transportsum = $tokenlog->where('createtime','> time',date('Y-m-d'))->where('user_id',$this->auth->id)->where('symbol','USD')->where('type','transportformyusd')->sum('num');
        $transportdsum = $tokenlog->where('createtime','> time',date('Y-m-d'))->where('user_id',$this->auth->id)->where('symbol','USD')->where('type','transportformdusd')->sum('num');

        $mineral = new MineralModel();
        $running = $mineral->where('user_id',$this->auth->id)->sum('num');


        $this->success('返回成功',['price'=>$price,'yield'=>$yield,'expiretime'=>$expiretime,'mineral_total'=>$mineral_total,'transport_min'=>$transport_min,'transport_multiple'=>$transport_multiple,'mineral_takefto_min'=>$mineral_takefto_min,'mineral_takefto_poundage'=>$mineral_takefto_poundage,'transportsum'=>$transportsum,'transportdsum'=>$transportdsum,'mineral_ad'=>$mineral_ad,'running'=>$running]);
    }

    /**
     * 获取用户正在运行中的矿机数 和 
     * @return [type]
     */
    private function getmineralnum($user_id)
    {
        $mineral = new MineralModel();
        $num = $mineral->where('user_id',$user_id)->sum('num');
        return $num;
    }


    /**
     * 我的矿机列表
     *
     * @ApiParams   (name="page", type="int", required=true, description="查询页数")
     * @ApiParams   (name="status", type="string", required=true, description="查询矿机状态 默认查询正字运行的矿机 running scrapped")
     */
    public function mymineral()
    {
        $page = $this->request->request('page',1);
        $status = $this->request->request('status','running');

        if (!in_array($status, ['running','scrapped'])) {
            $this->error('输入的矿机状态不正确！code running || scrapped');
        }
        $mineral = new MineralModel();
        $minerals=$mineral->where('user_id',$this->auth->id)->where('status',$status)->limit(10)->page($page)->select();
        $this->success('返回成功',['list'=>$minerals]);
    }

    /**
     * 矿机详情
     * 
     * @param int $id 矿机id
     */
    public function mineralinfo()
    {
        $id = $this->request->request('id',0);
        if ($id == 0) {
            $this->error('请传矿机id');
        }
        $mineral = new MineralModel();

        $info=$mineral->where('user_id',$this->auth->id)->where('id',$id)->find();
        if (!$info) {
            $this->error('找不到矿机，请检查');
        }
        $info['logs']=model('mineral_log')->where('user_id',$this->auth->id)->where('mineral_id',$info['id'])->select();
        $this->success('返回成功',['info'=>$info]);
    }


    /**
     * 购买矿机
     *
     * @param int $num 购买的矿机数量
     * @param [type] $[name] [<description>]
     */
    public function buy()
    {
        $num = $this->request->request('num',0);
        if ($num == 0) {
            $this->error('请填写数量');
        }
        $mineral = new MineralModel();
        $mineralnum=$mineral->where('user_id',$this->auth->id)->where('createtime',strtotime(date('Y-m-d')) + 86400)->count();

        if ($mineralnum) {
            $this->error('每天只能购买一次广告包');
        }

        $user = $this->auth->getUser();
        $price = config('site.mineral_price');
        $yield = config('site.mineral_yield');
        $expiretime = config('site.mineral_expiretime');
        $token = $this->auth->getUserToken();
        $total = $price*$num;
        if ($token->USD < $total) {
            $this->error('您的USD不足');
        }

        MineralModel::create([
            'user_id'   =>  $this->auth->id,
            'num'       =>  $num,
            'price'     =>  $price,
            'createtime'=>  strtotime(date('Y-m-d')) + 86400,
            'expiretime'=>  strtotime(date('Y-m-d')) + 86400 + ($expiretime*86400),
            'yield'     =>  $yield*$num,
        ]);
        User::tokenlog('USD',$this->auth->id,0,-$total,'buymineral','购买广告包');
        Hook::listen("user_buy_mineral",$user,$total);
        $this->success('购买成功');
    }

    /**
     * 完成任务开始出矿
     * 权限不正确 理应系统外部无法调用
     */
    public function mining()
    {
        $mineral = new MineralModel();
        $minerals=$mineral
            ->where('user_id',$this->auth->id)
            ->where('status','running')
            ->where('createtime','< time',time())
            // ->where('expiretime','> time',time())
            ->where('already',0)
            ->select();
        // $mineral_rule = config('site.mineral_rule');
        $mineral_static = config('site.mineral_static');
        $mineral_give_fae = config('site.mineral_give_fae');

        
        $userlevel = $this->auth->getUserinfo()['level'];
        $static = $mineral_static[$userlevel];
        // echo $static;
        // die;
        foreach ($minerals as $key => $m) {
            $today=bcmul($m['num']*$m['price'], bcdiv(floatval($static),100,4),2);
            if ($today + $m['total'] > $m['yield']) {
                $today = $m['yield'] - $m['total'];
            }
            if ($today==0) {
                continue;
            }
            $mineral->where('id',$m['id'])->inc('today',$today)->inc('total',$today)->update(['already'=>1]);
            // User::score($today,$this->auth->id,'mining');
            // User::tokenlog('USD',$this->auth->id,0,$today,'mining','矿机出矿');
            User::mineralscore($today,$this->auth->id,$m['id'],'mining');


            User::tokenlog('YUSD',$this->auth->id,0,$today,'mining','产出USD');
            User::tokenlog('FAE',$this->auth->id,0,$today*bcdiv($mineral_give_fae,100,3),'mining','矿机出矿 赠送FAE');
            
            // User::mineralscore($today,$this->auth->id,$m['id'],'mining');
        }
        // $this->success('矿机已出矿');
        return true;
    }

    /**
     * 划转USD
     *
     * @param int $num 划转的数量
     */
    public function transport()
    {
        $num = $this->request->request('num/d',0);
        $paypwd = $this->request->request('paypwd','');
        Hook::listen("check_paypwd",$paypwd);

        $transport_min = config('site.mineral_transport_min');
        $transport_multiple = config('site.mineral_transport_multiple');
        $mineral_transport_limit = config('site.mineral_transport_limit');
        $level = $this->auth->getUserinfo()['level'];
        $tokenlog = new Tokenlog();
        $sum = $tokenlog->where('createtime','> time',date('Y-m-d'))->where('user_id',$this->auth->id)->where('symbol','USD')->where('type','transporttoyb')->sum('num');
        // if ($mineral_transport_limit[$level] < $sum || $mineral_transport_limit[$level] < $sum + $num) {
        //     $this->error('每日划转超过当前等级划转限制');
        // }
        if ($transport_min > $num) {
            $this->error(__('不能少于'.$transport_min));
        }
        if ($num % $transport_multiple != 0) {
            $this->error(__('请输入'.$transport_multiple.'的倍数'));
        }
        $token = $this->auth->getUserToken();
        if ($token->YUSD >= $num) {
            User::tokenlog('YUSD',$this->auth->id,0,-$num,'transport','划转到USD');
            User::tokenlog('USD',$this->auth->id,0,$num,'transportformyusd','划转到USD');
            $this->success('划转成功');
        }else{
            $this->error('数量不足');
        }
    }

    /**
     * 划转USD
     *
     * @param int $num 划转的数量
     */
    public function transportd()
    {
        $num = $this->request->request('num/d',0);
        $paypwd = $this->request->request('paypwd','');
        Hook::listen("check_paypwd",$paypwd);

        $transport_min = config('site.mineral_transport_min');
        $transport_multiple = config('site.mineral_transport_multiple');
        $mineral_transport_limit = config('site.mineral_transport_limit');
        $level = $this->auth->getUserinfo()['level'];
        $tokenlog = new Tokenlog();
        $sum = $tokenlog->where('createtime','> time',date('Y-m-d'))->where('user_id',$this->auth->id)->where('symbol','USD')->where('type','transporttousd')->sum('num');
        if ($mineral_transport_limit[$level] < $sum || $mineral_transport_limit[$level] < $sum + $num) {
            $this->error('每日划转超过当前等级划转限制');
        }
        if ($transport_min > $num) {
            $this->error(__('不能少于'.$transport_min));
        }
        if ($num % $transport_multiple != 0) {
            $this->error(__('请输入'.$transport_multiple.'的倍数'));
        }
        $token = $this->auth->getUserToken();
        if ($token->DUSD >= $num) {
            User::tokenlog('DUSD',$this->auth->id,0,-$num,'transport','划转到USD');
            User::tokenlog('USD',$this->auth->id,0,$num,'transportformdusd','划转到USD');
            $this->success('划转成功');
        }else{
            $this->error('数量不足');
        }
    }

    /**
     * 我的矿场架构 （推荐架构）
     *
     * @param int $referee_id 推荐人的id，传0默认为自己，传其他id为查询团队成员架构
     */
    public function frame()
    {
        $referee_id = $this->request->request('referee_id',$this->auth->id);

        if ($referee_id == 0) {
            $referee_id = $this->auth->id;
        }

        $user = new User();
        $field = 'id,nickname,username,mobile,level,avatar,status,active';
        $users = $user->where('referee_id',$referee_id)->field($field)->select();
        $shangji = $user->where('id',$referee_id)->value('referee_id');
        $this->success('返回成功',['list'=>$users,'referee_id'=>$shangji]);
    }

    /**
     * 查询矿场架构会员
     *
     * @param string $username 要查询的会员名称
     * @return [type] [description]
     */
    public function queryframe()
    {
        $username = $this->request->request('username','');
        $user = new User();
        $field = 'id,nickname,username,mobile,level,avatar,status,active';
        $users = $user->where('username','like','%'.$username.'%')->where('path','like',','.$this->auth->id.',')->field($field)->select();
        $this->success('返回成功',['list'=>$users]);
    }


    /**
     * 协同挖矿
     *
     * @ApiParams   (name="page", type="int", required=true, description="查询页数")
     */
    public function synergetic()
    {
        $page = $this->request->request('page/d',1);
        $tokenlog = new Tokenlog();

        $logs = $tokenlog->where('user_id',$this->auth->id)->where('type','synergetic')->order('id desc')->page($page)->limit(10)->select();
        $total = $tokenlog->where('user_id',$this->auth->id)->where('type','synergetic')->order('id desc')->sum('num');
        foreach ($logs as $key => $log) {
            $log->touser;
        }
        $this->success('返回成功',['list'=>$logs,'total'=>$total]);
    }

    /**
     * 提币
     *
     * @ApiParams   (name="num", type="int", required=true, description="提取数量")
     * @ApiParams   (name="tokenaddress", type="string", required=true, description="钱包地址")
     * @ApiParams   (name="type", type="string", required=true, description="提币类型")
     */
    public function takeico()
    {
        $num = $this->request->request('num/d',1);
        $tokenaddress = $this->request->request('tokenaddress','');
        if ($tokenaddress=='') {
            $this->error('请输入钱包地址');
        }
        $type = $this->request->request('type');

        if (!in_array($type, ['FAE'])) {
            $this->error();
        }

        $mineral_takefto_min = config('site.mineral_takefto_min');
        $mineral_takefto_poundage = config('site.mineral_takefto_poundage');

        if ($num < $mineral_takefto_min) {
            $this->error('最低提'.$mineral_takefto_min);
        }

        $pre = bcdiv($mineral_takefto_poundage, 100,2);

        $poundage = bcmul($pre,$num,4);

        $token = $this->auth->getUserToken();
        $total = $poundage + $num;
        if ($token->FAE < $total) {
            $this->error('您的FAE不足'.$total);
        }
        if (User::tokenlog('FAE',$this->auth->id,0,-$total,'takeicofto','提币')) {
            Takeico::create([
                'user_id'   =>  $this->auth->id,
                'icotype'   =>  'FAE',
                'tokenaddress'  =>  $tokenaddress,
                'num'       =>  $num,
                'reply'     =>  ''
            ]);
            $this->success('提币成功');
        }else{
            $this->error('发生错误');
        }
    }

    function getmytakeico()
    {
        $page = $this->request->request('page/d',1);
        $takeico = new Takeico();
        $list = $takeico->page($page)->limit(15)->where('user_id',$this->auth->id)->select();
        $this->success('获取成功',['list'=>$list]);
    }
}
